package com.yizhang.sqlSession;

import com.yizhang.executor.Executor;
import com.yizhang.pojo.Configuration;
import com.yizhang.pojo.MappedStatement;

import java.lang.reflect.*;
import java.util.Collection;
import java.util.List;

/**
 * @Author: yi.zhang
 * @CreateTime: 2025-05-27 17:29:49
 * @Description: 构建查询query
 */
public class DefaultSqlSession implements SqlSession {

    private Configuration configuration;

    private Executor executor;

    public DefaultSqlSession(Configuration configuration, Executor executor) {
        this.configuration = configuration;
        this.executor = executor;
    }

    @Override
    public <E> List<E> selectList(String statementId, Object parameter) throws Exception {
        MappedStatement mappedStatement = configuration.getMappedStatementMap().get(statementId);
        return executor.query(configuration, mappedStatement, parameter);
    }

    @Override
    public <T> T selectOne(String statementId, Object parameter) throws Exception {
        List<Object> list = this.selectList(statementId, parameter);
        if (list != null && list.size() == 1) {
            return (T) list.get(0);
        } else if (list != null && list.size() > 1) {
            throw new RuntimeException("返回结果大于1");
        }
        return null;
    }

    @Override
    public <T> T getMapper(Class<?> mapperClass) {
        Object proxy = Proxy.newProxyInstance(DefaultSqlSession.class.getClassLoader(), new Class[]{mapperClass}, new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                // 获取statementId
                String methodName = method.getName();
                String className = method.getDeclaringClass().getName();
                String statementId = className + "." + methodName;

                // 根据sql标签来选择需要执行的方法
                MappedStatement mappedStatement = configuration.getMappedStatementMap().get(statementId);
                String sqlType = mappedStatement.getSqlType();
                switch (sqlType) {
                    case "select":
                        Class<?> returnType = method.getReturnType();
                        // 判断是否是集合类型
                        boolean assignableFrom = Collection.class.isAssignableFrom(returnType);
                        if (assignableFrom) {
                            if (args != null) {
                                return selectList(statementId, args[0]);
                            }
                            return selectList(statementId, null);
                        }
                        return selectOne(statementId, args[0]);
                    case "update":

                    case "insert":

                    case "delete":
                }

                return null;
            }
        });
        return (T) proxy;
    }
}
